﻿using System;

using System.Collections.Generic;
using System.Text;
using Silvermoon.Controls.Base;
using Silvermoon.Shapes;
using System.Drawing;
using Silvermoon.UI;
using Silvermoon.Windows;

namespace Silvermoon.Controls
{
    public class ToggleButton : ToggleButtonBase
    {
        #region fields


        private Shape onContent;
        private Shape offContent;
        private PointF onOffset;
        private PointF offOffset;

        #endregion
        #region accessors

        public static PropertyAccessor<ToggleButton, PointF> OnOffsetProperty = PropertyAccessor.Register<ToggleButton, PointF>(
            "OnOffset",
            c => c.OnOffset,
            (c, v) => c.OnOffset = v);

        public static PropertyAccessor<ToggleButton, PointF> OffOffsetProperty = PropertyAccessor.Register<ToggleButton, PointF>(
            "OffOffset",
            c => c.OffOffset,
            (c, v) => c.OffOffset = v);

        public static PropertyAccessor<ToggleButton, int> OnOpacityProperty = PropertyAccessor.Register<ToggleButton, int>(
            "OnOpacity",
            c => c.OnOpacity,
            (c, v) => c.OnOpacity = v);

        public static PropertyAccessor<ToggleButton, int> OffOpacityProperty = PropertyAccessor.Register<ToggleButton, int>(
            "OffOpacity",
            c => c.OffOpacity,
            (c, v) => c.OffOpacity = v);

        #endregion
        #region ctors

        static ToggleButton()
        {
            VisualStateManager.RegisterClassManager(typeof(ToggleButton), ToggleButtonManagers.ToggleButtonManager);
        }

        public ToggleButton()
            : base()
        {
            size = new Size(120, 64);
        }

        #endregion
        #region props

        public int OnOpacity
        {
            get { return onContent != null ? onContent.Opacity : 0; }
            set
            {
                if (onContent != null)
                {
                    onContent.Opacity = value;
                    Invalidate(InvalidationFlag.Appearance);
                }
            }
        }

        public int OffOpacity
        {
            get { return offContent != null ? offContent.Opacity : 0; }
            set
            {
                if (offContent != null)
                {
                    offContent.Opacity = value;
                    Invalidate(InvalidationFlag.Appearance);
                }
            }
        }

        public PointF OnOffset
        {
            get { return onOffset; }
            set
            {
                if (onOffset != value)
                {
                    onOffset = value;
                    Invalidate(InvalidationFlag.LayoutAppearance);
                }
            }
        }

        public PointF OffOffset
        {
            get { return offOffset; }
            set
            {
                if (offOffset != value)
                {
                    offOffset = value;
                    Invalidate(InvalidationFlag.LayoutAppearance);
                }
            }
        }

        public Shape OnContent
        {
            get { return onContent; }
            set
            {
                if (onContent != value)
                {
                    if (onContent != null)
                    {
                        Shapes.Remove(onContent);
                        onContent.Dispose();
                    }
                    onContent = value;
                    OnOnContentChanged();
                }
            }
        }

        public Shape OffContent
        {
            get { return offContent; }
            set
            {
                if (offContent != value)
                {
                    if (offContent != null)
                    {
                        Shapes.Remove(offContent);
                        offContent.Dispose();
                    }
                    offContent = value;
                    OnOffContentChanged();
                }
            }
        }

        #endregion
        #region methods

        protected override void ApplyStyle()
        {
            base.ApplyStyle();
        }

        protected override Shape CreateDefaultBackground()
        {
            return new ButtonShape();
        }

        protected virtual void OnOnContentChanged()
        {
            Invalidate(InvalidationFlag.LayoutAppearance);
        }

        protected virtual void OnOffContentChanged()
        {
            Invalidate(InvalidationFlag.LayoutAppearance);
        }

        protected override void OnLayout()
        {
            if (CheckFlag(InvalidationFlag.Layout))
            {
                Shapes.Clear();
                if (Background != null) Shapes.AddLast(Background);
                if (offContent != null) Shapes.AddLast(offContent);
                if (onContent != null && onContent != offContent) Shapes.AddLast(onContent);
            }
            if (CheckFlag(InvalidationFlag.Layout | InvalidationFlag.Size))
            {

                if (onContent != null) onContent.Bounds = GetBounds(onContent, onOffset);
                if (offContent != null && offContent != onContent) offContent.Bounds = GetBounds(offContent, offOffset);
            }

            base.OnLayout();
        }

        private Rectangle GetBounds(Shape shape, PointF offset)
        {
            Rectangle bounds = Margin.Centered.Layout(shape.Bounds, Size);

            int dx = (int)(offset.X * Width);
            int dy = (int)(offset.Y * Height);
            bounds.Offset(dx, dy);
            return bounds;
        }

        #endregion
    }
}
